package com.wh1200.mybatis.xmlless.model.visitor

import com.wh1200.mybatis.xmlless.dialect.DialectFactory
import com.wh1200.mybatis.xmlless.model.MethodInfo
import com.wh1200.mybatis.xmlless.model.criteria.CriteriaParameter
import com.wh1200.mybatis.xmlless.util.ColumnUtils
import com.wh1200.mybatis.xmlless.util.toParameterHolder
import net.sf.jsqlparser.expression.ExpressionVisitorAdapter
import net.sf.jsqlparser.expression.Function
import net.sf.jsqlparser.schema.Column

/**
 *
 * @author 吴昊
 * @date 2024/1/28 15:39
 * @since v4.0.0
 * @version 1.0
 */
class ReplaceToParamVisitor(
  private val parameters: List<CriteriaParameter>,
  private val methodInfo: MethodInfo,
  private val isSqlSet: Boolean = false
) : ExpressionVisitorAdapter() {

  override fun visit(col: Column) {
    if (col.columnName in listOf("true", "TRUE")) {
      col.columnName = "TRUE"
      return
    }
    if (col.columnName in listOf("false", "FALSE")) {
      col.columnName = "FALSE"
      return
    }
    if (isSqlSet && !col.columnName.startsWith("#")) {
      val mapping = methodInfo.mappings.mappings.find { it.property == col.columnName } ?: error("无法识别的属性${col}")
      col.columnName = ColumnUtils.wrapColumn(mapping.tableFieldInfo.column)
    } else {
      val colName = when {
        col.columnName.startsWith("#") -> col.columnName.drop(1)
        else -> col.columnName
      }
      val parameter = parameters.find { it.name.origin == colName }
      if (parameter != null) {
        col.columnName = toParameterHolder(parameter.name.name)
      } else {
        col.columnName = toParameterHolder(colName)
      }
    }
  }

  override fun visit(function: Function) {
    if (function.name.lowercase() in listOf("date", "month", "year")) {
      val dialect = DialectFactory.getDialect(methodInfo.dbType)
      dialect.replaceDateFunction(function)
    }
    super.visit(function)
  }

}
